package rock.remoting.transmit.socket;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import rock.common.extension.ExtensionLoader;
import rock.exception.RpcException;
import rock.registry.ServiceDiscovery;
import rock.remoting.dto.RpcRequest;
import rock.remoting.transmit.RpcRequestTransmit;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

@AllArgsConstructor
@Slf4j
public class SocketRpcClient implements RpcRequestTransmit {

    private final ServiceDiscovery discovery;

    public SocketRpcClient() {
        // load discovery from config:zk
        this.discovery = ExtensionLoader.getExtensionLoader(ServiceDiscovery.class).getExtension("zk");
    }

    /**
     * 通过socket 发送rpc请求
     * @param request message body
     * @return server返回
     */
    @Override
    public Object sendRpcRequest(RpcRequest request) {
        // 服务发现
        InetSocketAddress inetSocketAddress = discovery.lookup(request);
        try (Socket socket = new Socket()) {
            socket.connect(inetSocketAddress);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            // send data to server
            oos.writeObject(request);

            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            // read response from server
            return ois.readObject();

        } catch (Exception e) {
            throw new RpcException("call rpc fail", e);
        }
    }
}
